package com.smt.modules.bus.service.impl;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.smt.common.enums.Code;
import com.smt.common.enums.EventEnum;
import com.smt.common.enums.StageEnum;
import com.smt.common.utils.*;
import com.smt.modules.app.utils.CurrentDayRewardUtil;
import com.smt.modules.bus.entity.*;
import com.smt.modules.bus.service.*;
import com.smt.modules.bus.vo.ProjectTaskVo;
import com.smt.modules.bus.vo.ProjectVo;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import com.smt.modules.bus.dao.ProjectDao;
import org.springframework.transaction.annotation.Transactional;


/**
 * 项目crud+项目任务crud
 */
@Slf4j
@Service("projectService")
public class ProjectServiceImpl extends ServiceImpl<ProjectDao, ProjectEntity> implements ProjectService {

    @Autowired
    private ProjectTaskService projectTaskService;

    @Autowired
    private GradeService gradeService;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private TeamManagementService teamManagementService;

    @Autowired
    private EventService eventService;

    @Autowired
    private CurrentDayRewardUtil currentDayRewardUtil;

    @Autowired
    private TeamService teamService;

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    private TemplateDataService templateDataService;

    @Autowired
    private AttachmentService attachmentService;

    @Autowired
    private SubtaskService subtaskService;

    @Autowired
    private MemberUserService memberUserService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<ProjectEntity> page = this.selectPage(
                new Query<ProjectEntity>(params).getPage(),
                new EntityWrapper<ProjectEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 创建项目 TODO
     *
     * @param project
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R save(ProjectVo project, MemberUserEntity memberUserEntity) {
        Integer industryId = project.getIndustryId();
        Long userId = memberUserEntity.getUserId();
        Boolean[] operateStatus = new Boolean[StageEnum.values().length];
        int index = 0;
        //创建项目个数 1 -> 1   2 -> 2
        GradeEntity gradeEntity3 = gradeService.selectOne(new EntityWrapper<GradeEntity>()
                .eq("member_id", userId));
        Integer level = gradeEntity3.getLevel();
        int count = projectService.selectCount(new EntityWrapper<ProjectEntity>()
                .eq("created_id", userId)
                .eq("is_delete", 0));
        if (level == 1) {
            if (count >= 1) {
                return R.error(1, "您只能创建一个项目,请升级后再创建项目");
            }
        } else if (level == 2) {
            if (count >= 2) {
                return R.error(2, "您只能创建两个项目,请升级后再创建项目");
            }
        }
        ProjectEntity projectEntity = new ProjectEntity();
        BeanUtils.copyProperties(project, projectEntity);
        //创建项目
        projectEntity.setCreatedId(userId);
        projectEntity.setCompanyId(memberUserEntity.getCompanyId());
        projectEntity.setCreateTime(DateTime.now().toDate());
        projectEntity.setUpdateTime(DateTime.now().toDate());
        projectEntity.setIsDelete(0);
        boolean projectFlag = insert(projectEntity);
        //创建各个阶段空白任务，对应阶段责任数据
        StageEnum[] values = StageEnum.values();
        if (projectFlag) {
            for (StageEnum s : values) {
                ProjectTaskEntity pte = new ProjectTaskEntity();
                pte.setProjectId(projectEntity.getId());
                pte.setMemberId(userId);
                pte.setStageMemberId(userId);
                pte.setStatus(Constant.EMPTY);
                pte.setStageId(s.key());
                pte.setCreateTime(DateTime.now().toDate());
                pte.setUpdateTime(DateTime.now().toDate());
                boolean success = projectTaskService.insert(pte);
                operateStatus[index++] = success;
            }
        }
        //删除初始化操作
        for (Boolean i : operateStatus) {
            if (!i) {
//                baseMapper.deleteProjectTask(Arrays.asList(operateStatus));
                log.info("创建阶段模板失败！状态：{}", i);
                return R.error(EnumToKeyUtil.toInt(Code.APPEND_DATA_ERROR), "新增数据失败");
            }
        }
        //新建事件管理模板
        boolean flag = false;
        Long pId = projectEntity.getId();
        EventManagementEntity ee = null;
        for (EventEnum e : EventEnum.values()) {
            String desc = e.desc();
            if (!flag) {
                flag = true;
                ee = new EventManagementEntity();
                ee.setTitle(desc);
                continue;
            }
            if (flag) {
                flag = false;
                ee.setColor(desc);
                ee.setCreateTime(DateTime.now().toDate());
                ee.setMemberId(userId);
                ee.setProjectId(pId);
                eventService.insert(ee);
            }
        }
        //是否选择模板，添加模板数据
        if (industryId != 0) {
            // 添加模板数据
            List<TemplateDataEntity> templateList = templateDataService.selectList(new EntityWrapper<TemplateDataEntity>()
                    .eq("template_id", industryId));
            Long projectEntityId = projectEntity.getId();
            //填充模板数据
            templateList.stream().forEach(t -> {
                ProjectTaskEntity pt = new ProjectTaskEntity();
                //创建项目实体
                pt.setProjectId(projectEntityId);
                pt.setMemberId(userId);
                pt.setStatus(0);
                pt.setStageId(t.getStageId());
                pt.setTaskName(t.getTitle());
                pt.setCreateTime(DateTime.now().toDate());
                pt.setUpdateTime(DateTime.now().toDate());
                pt.setStageMemberId(userId);
                pt.setRemark(null);
                projectTaskService.insert(pt);
            });

        }
        if (projectFlag) {
            boolean team = teamManagementService.createTeam(userId, projectEntity.getId());
            log.info("创建项目时候创建团队，创建状态{}", team);
            return R.ok("新增项目成功");
        } else {
            return R.error(3, "新增项目失败");
        }


    }

    /**
     * 获取项目列表
     *
     * @return
     */
    @Override
    public R projectLists(MemberUserEntity memberUserEntity) {
        Long userId = memberUserEntity.getUserId();
        //当前成员加入过的项目 每一个项目有一个团队，此时人员存储在这个团队中
        List<TeamEntity> teamList = teamService.selectList(new EntityWrapper<TeamEntity>()
                .eq("member_id", userId)
                .eq("member_exist",0));
        if (teamList.size() == 0) {
            return R.error(EnumToKeyUtil.toInt(Code.QUERY_DATA_ERROR), "当前项目不存在");
        }
        List<ProjectEntity> projectEntities = new ArrayList<>();
        for (TeamEntity t : teamList) {
            Wrapper<ProjectEntity> projectWrapper = new EntityWrapper<ProjectEntity>()
                    .eq("id", t.getProjectId())
                    .eq("is_delete", 0);
            ProjectEntity projectEntity = projectService.selectOne(projectWrapper);
            //从团队中将其成员剔除的项目去除
            EntityWrapper<TeamEntity> teamEntityEntityWrapper = new EntityWrapper<TeamEntity>();
            if (projectEntity != null) {
                Long projectEntityId = projectEntity.getId();
                if (projectEntity.getCreatedId().equals(userId)) {
                    //该项目是创建者
                    projectEntity.setShibushiwochuangjiande(1);
                } else {
                    //该用户是在此项目的中的成员
                    projectEntity.setShibushiwochuangjiande(0);
                    teamEntityEntityWrapper
                            .eq("member_id", userId);
                }
                MemberUserEntity memberU = memberUserService.selectById(projectEntity.getCreatedId());
                if (!Objects.isNull(memberU)) {
                    projectEntity.setUserName(memberU.getUsername());
                }
                //将此团队中的无效成员状态禁止加入该项目
                List<TeamEntity> memberExistList = teamService.selectList(teamEntityEntityWrapper.eq("project_id", projectEntityId));
                    if (t.getMemberExist().equals(0)) {
                        projectEntities.add(projectEntity);
                    }
            }
        }

        //日期排序
        Collections.sort(projectEntities,(x,y) -> {
            DateTime createTime = new DateTime(x.getCreateTime());
            DateTime createTime1 = new DateTime(y.getCreateTime());
            Days days = Days.daysBetween(createTime, createTime1);
            int days1 = days.getDays();
            if(days1 > 0){
                return 1;
            }else if(days1 < 0){
                return -1;
            }else{
                return days1;
            }
        });
        return R.ok().put("projects", projectEntities);
    }

    /**
     * 修改项目
     *
     * @param projectVo
     * @return
     */
    @Override
    public R projectEdit(ProjectVo projectVo, MemberUserEntity entity) {
        ProjectEntity projectEntity = new ProjectEntity();
        //验证当前用户是否是创建者
        if (projectVo != null) {
            Long creatorId = baseMapper.selectCreator(projectVo.getCreatedId());
            if (creatorId.equals(entity.getUserId())) {
                BeanUtils.copyProperties(projectVo, projectEntity);
                int i = baseMapper.updateProject(projectEntity);
                return i == 0 ? R.error(4, "修改项目失败！") : R.ok("修改项目成功");
            } else {
                return R.error(EnumToKeyUtil.toInt(Code.MISSING_PERMISSION), "您不是项目创建者！");
            }
        } else {
            return R.error("无效修改,传参为空!");
        }
    }

    /**
     * 修改当前项目
     *
     * @param projectVo
     * @param entity
     * @return
     */
    @Override
    public R currentProjectEdit(ProjectVo projectVo, MemberUserEntity entity) {
        Long memberId = entity.getUserId();
        ProjectEntity projectEntity = new ProjectEntity();
        //判断权限是否合法
        Long createdId = projectVo.getCreatedId();
        if (createdId.equals(memberId)) {
            BeanUtils.copyProperties(projectVo, projectEntity);
            boolean su = updateById(projectEntity);
            Long projectId = projectEntity.getId();
            //当操作是删除的时候
            Integer isDelete = projectVo.getIsDelete();
            if (isDelete != null && isDelete.equals(1)) {
                //更新团队信息
                List<TeamEntity> teamList = teamService.selectList(new EntityWrapper<TeamEntity>().eq("project_id", projectId));
                teamList.stream().forEach(t -> {
                    if (t.getProjectId().equals(projectId)) {
                        TeamEntity teamEntity = new TeamEntity();
                        teamEntity.setId(t.getId());
                        teamEntity.setProjectId(new Long(0));
                        teamService.updateById(teamEntity);
                    }
                });

            }
            return su ? R.ok("项目修改成功") : R.error(EnumToKeyUtil.toInt(Code.UPDATE_FAIL), "项目修改失败！");
        } else {
            return R.error(EnumToKeyUtil.toInt(Code.MISSING_PERMISSION), "您不是项目创建者，无法修改项目！");
        }
    }

    /**
     * 通过项目id获取项目内容
     *
     * @param projectId
     * @return
     */
    @Override
    public R getProjectById(Long projectId) {
        ProjectEntity projectEntity = selectById(projectId);
        ProjectVo projectVo = new ProjectVo();
        BeanUtils.copyProperties(projectEntity, projectVo);
        return R.ok().put("project", projectVo);
    }

    /**
     * 获取该用户下的所有项目名字
     *
     * @param memberUserEntity
     * @return
     */
    @Override
    public R getProjectNameList(MemberUserEntity memberUserEntity) {
        Long userId = memberUserEntity.getUserId();
        List<ProjectVo> projectVo = baseMapper.projectNameList(userId);
        List<Map<String, String>> listName = new ArrayList<>();
        projectVo.stream()
                .forEach(p -> {
                    Map<String, String> map = new ConcurrentHashMap<>();
                    map.put("id", String.valueOf(p.getId()));
                    map.put("projectName", p.getProjectName());
                    listName.add(map);
                });
        return R.ok().put("idAndName", listName);
    }

    /**
     * 任务修改认证权限判断
     *
     * @param projectTaskVo
     * @param memberUserEntity
     * @return
     */
    @Override
    public R projectTaskEdit(ProjectTaskVo projectTaskVo, MemberUserEntity memberUserEntity) {
        Long userId = memberUserEntity.getUserId();
        Long memberId = projectService.selectById(projectTaskVo.getProjectId()).getCreatedId();

        Integer status1 = projectTaskVo.getStatus();
        if (memberId.equals(userId) || projectTaskVo.getStageMemberId().equals(userId)) {
            Long id = projectTaskVo.getId();
            ProjectTaskEntity pt = projectTaskService.selectOne(new EntityWrapper<ProjectTaskEntity>()
                    .eq("id", id));
            Long formUserId = pt.getMemberId();
            currentDayRewardUtil.issueRewards(Constant.DAY_3, formUserId);
            //添加日程
            if (id != null && projectTaskVo.getEndTime() != null) {
                scheduleService.addScheduleInfo(projectTaskVo);
            }
            //判断子任务是否完成
            int subEnd = isSubEnd(projectTaskVo, userId);
            switch (subEnd){
                case 0:
                    return R.error(6, "您的权限不够，无法修改");
                case 1:
                    return R.ok("项目修改成功");
                case 2:
                    return R.error("项目修改失败");
                case 3:
                    return R.error(EnumToKeyUtil.toInt(Code.UPDATE_FAIL), "当前子任务未完成！");
                default:
                    break;
            }
        }else {
            //该代码块是重复，在当前操作者是该任务负责人时候，并且是确认完成的时候
            if (status1 != null && status1.equals(50) && userId.equals(projectTaskVo.getMemberId())) {
                //本人任务修改
                //当前是要完成任务，但是需求说在所有子任务为完成前不能完成，所以在这里要把这个任务下的子任务获取到加以判断
                Long sPiId = projectTaskVo.getId();
                List<SubtaskEntity> sub = subtaskService.selectList(new EntityWrapper<SubtaskEntity>()
                        .eq("project_task_id", sPiId)
                        .in("status", Constant.SQL_CON));
                boolean flag = true;
                for (SubtaskEntity s : sub) {
                    if (!s.getStatus().equals(1)) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    ProjectTaskEntity proT = projectTaskService.selectOne(new EntityWrapper<ProjectTaskEntity>()
                            .eq("id", sPiId));
                    //修改项目
                    boolean bb = editProjectInfo(projectTaskVo);
                    //奖励发放
                    Long formUserId = proT.getMemberId();
                    currentDayRewardUtil.issueRewards(Constant.DAY_3, formUserId);
                    return bb ? R.ok("项目修改成功") : R.error("项目修改失败");
                } else {
                    return R.error(EnumToKeyUtil.toInt(Code.UPDATE_FAIL), "当前子任务未完成！");
                }
            }
        }
        return R.error(6, "您的权限不够，无法修改");
    }

    /**
     * 初始化展示阶段下的任务集合
     *
     * @param projectId
     * @return
     */
    @Override
    public R projectManageShow(Long projectId) {
        //获取项目基本信息
        ProjectEntity projectEntity = selectById(projectId);
        List<ProjectTaskEntity> projectTaskList = projectTaskService.getProjectTaskList(projectId);
        List<ProjectTaskEntity> firstProjectTask = new ArrayList<>();
        if (projectTaskList != null) {
            //取各个阶段的任务
            projectTaskList.stream()
                    .forEach(e -> {
                        if (e.getStageId().equals(StageEnum.CONCEPT_STAGE)) {
                            firstProjectTask.add(e);
                        }
                    });
            return R.ok()
                    .put("project", projectEntity)
                    .put("projectTaskList", firstProjectTask);
        } else {
            return R.error(7, "任务集合为空");
        }
    }

    /**
     * 获取项目阶段下的用户集合
     *
     * @param projectId
     * @return
     */
    @Override
    public R projectStageUser(Long projectId, Integer stageId, MemberUserEntity memberUserEntity) {
        Integer r = projectTaskService.selectStageUserName(projectId, stageId, memberUserEntity);
        return R.ok().put("name", r);
    }

    /**
     * 阶段负责人修改
     *
     * @param projectTaskVo
     * @param userId
     * @return
     */
    @Override
    public boolean editStageName(ProjectTaskVo projectTaskVo, long userId) {
        Long projectId = projectTaskVo.getProjectId();
        Integer stageId = projectTaskVo.getStageId();
        Long stageMemberId = projectTaskVo.getStageMemberId();

        ProjectEntity projectEntity = selectById(projectId);
        boolean equals = projectEntity.getCreatedId().equals(userId);
        if (equals) {
            ProjectTaskEntity projectTaskEntity = new ProjectTaskEntity();
            projectTaskEntity.setProjectId(projectId);
            projectTaskEntity.setStageId(stageId);
            projectTaskEntity.setStageMemberId(stageMemberId);
            return projectTaskService.update(projectTaskEntity, new EntityWrapper<ProjectTaskEntity>()
                    .eq("project_id", projectId)
                    .eq("stage_id", stageId));
        } else {
            return false;
        }
    }

    /**
     * 获取项目下的各个阶段的任务集合 TODO
     *
     * @param projectId
     * @param stageId
     * @return
     */
    @Override
    public R getTaskList(Long projectId, Integer stageId) {
        List<ProjectTaskEntity> projectTaskEntityList = null;
        Wrapper<ProjectTaskEntity> in = new EntityWrapper<ProjectTaskEntity>()
                .eq("project_id", projectId)
                .in("status", Constant.SQL_CON);
        //判断当前是否是修改者
        //当获取阶段6的时候加以拦截
        if (stageId.equals(StageEnum.LIFE_STAGE.key())) {
            projectTaskEntityList = projectTaskService.selectList(in.eq("stage_id", StageEnum.MASS_PRODUCTION_STAGE.key()));
            for (ProjectTaskEntity p : projectTaskEntityList) {
                if (!p.getStatus().equals(1)) {
                    return R.ok("您的自产试产阶段任务未完成！").put("code", 34089);
                }
            }
        }
        projectTaskEntityList = projectTaskService.selectList(new EntityWrapper<ProjectTaskEntity>()
                .eq("project_id", projectId)
                .in("status", Constant.SQL_CON)
                .eq("stage_id", stageId)
                .eq("member_exist", 0));
        projectTaskEntityList.stream()
                .forEach(p -> {
                    Date localTime = new DateTime().withTimeAtStartOfDay().toLocalDateTime().toDate();
                    DateTime startTime = new DateTime(localTime);
                    DateTime endTime = new DateTime(p.getEndTime());
                    if (p.getStartTime() == null || p.getEndTime() == null) {
                        p.setDays(Integer.MAX_VALUE);
                    } else {
                        int days = Days.daysBetween(startTime, endTime).getDays();
                        if (days == 0) {
                            p.setDays(days);
                        } else {
                            p.setDays(days);
                        }
                    }
                    if (p.getMemberExist() == 1) {
                        p.setMemberId(null);
                    }
                    //添加文件状态信息
                    List<AttachmentEntity> attachmentEntity = attachmentService.selectList(new EntityWrapper<AttachmentEntity>()
                            .eq("project_task_id", p.getId())
                            .orderBy("create_time", false));
                    if (null != attachmentEntity && attachmentEntity.size() != 0) {
                        p.setHaveFile(1);
                        String fileName = attachmentEntity.get(0).getFileName();
                        fileName = fileName.substring(Constant.FILE_TOKEN.length() + 1, fileName.length());
                        p.setFileName(fileName);
                    } else {
                        p.setHaveFile(0);
                    }
                });
        return R.ok().put("projectList", projectTaskEntityList);
    }

    /**
     * 0：status=0 或者 status != 50 当前操作者没有权限
     * 1：任务修改成功
     * 2：任务修改失败
     * 3：当前子任务未完成
     *
     * @param projectTaskVo
     * @param userId
     * @return
     */
    private int isSubEnd(ProjectTaskVo projectTaskVo, Long userId) {
        Integer status = projectTaskVo.getStatus();
        //此时判断其状态是成功的时候
        if(status != null && (status.equals(Constant.SUPER_ADMIN) || status.equals(Constant.S_WORKING_401))){
            if(status.equals(Constant.S_WORKING_401)){
                Date endTime = projectTaskVo.getEndTime();
                Date startTime = DateTime.now().toDate();
                if(Objects.isNull(endTime)){
                    projectTaskVo.setStatus(0);
                }else{
                    //判断日期是否过期
                    int days = Days.daysBetween(new DateTime(startTime), new DateTime(endTime)).getDays();
                    if (days <= 0) {
                        projectTaskVo.setStatus(2);
                    }else{
                        projectTaskVo.setStatus(0);
                    }
                }
            }
            return editProjectInfo(projectTaskVo)?1:2;
        }else if(status != null && status.equals(Constant.S_WORKING_50) && userId.equals(projectTaskVo.getMemberId())) {
            //本人任务修改
            //当前是要完成任务，但是需求说在所有子任务为完成前不能完成，所以在这里要把这个任务下的子任务获取到加以判断
            Long sPiId = projectTaskVo.getId();
            List<SubtaskEntity> sub = subtaskService.selectList(new EntityWrapper<SubtaskEntity>()
                    .eq("project_task_id", sPiId)
                    .in("status",Constant.SQL_CON));
            boolean flag = true;
            for (SubtaskEntity s : sub) {
                if (!s.getStatus().equals(Constant.SUPER_ADMIN)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                ProjectTaskEntity proT = projectTaskService.selectOne(new EntityWrapper<ProjectTaskEntity>()
                        .eq("id", sPiId));
                //修改项目
                boolean bb = editProjectInfo(projectTaskVo);
                //奖励发放
                Long formUserId = proT.getMemberId();
                currentDayRewardUtil.issueRewards(Constant.DAY_3, formUserId);
                return bb ? 1 : 2;
            } else {
                return 3;
            }
        }else if(status == null){
            //当修改的是非状态的其他项时，是可以修改的
            boolean b = editProjectInfo(projectTaskVo);
            return b?1:2;
        }else{
            return 0;
        }
    }

    /**
     * 直接修改项目状态方法
     *
     * @param projectTaskVo
     * @return
     */
    private boolean editProjectInfo(ProjectTaskVo projectTaskVo){
        ProjectTaskEntity projectTaskEntity = new ProjectTaskEntity();
        BeanUtils.copyProperties(projectTaskVo, projectTaskEntity);
        projectTaskEntity.setId(projectTaskVo.getId());
        projectTaskEntity.setMemberId(projectTaskVo.getMemberId());
        projectTaskEntity.setMemberExist(0);
        return projectTaskService.updateById(projectTaskEntity);
    }
}